package com.qsl.system.config;


import com.qsl.system.custom.CustomMd5PasswordEncoder;
import com.qsl.system.fillter.TokenAuthenticationFilter;
import com.qsl.system.fillter.TokenLoginFilter;
import com.qsl.system.service.LoginLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * SpringSecurity权限框架- 继承拦截器：WebSecurityConfigurerAdapter
 */
@Configuration //配置类
@EnableWebSecurity // 开启SpringSecurity权限框架
//@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启SpringSecurity权限注解,默认false
public class WebSecurityconfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private CustomMd5PasswordEncoder customMd5PasswordEncoder;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LoginLogService loginLogService;


    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    // configure可配置多个
    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 关键配置，决定那些接口开启防护，哪些接口绕过防护
        http.csrf().disable()   //关闭csrf
                .cors().and().authorizeRequests() // 开启跨域于便前端调用接口
                .antMatchers("/admin/system/index/login").permitAll()  // 指定登录等接口不需要验证即可访问
                .anyRequest().authenticated() // 其他所有借款需要认证才能访问
                .and()
                /* TokenAuthenticationFilter放到UsernamePasswordAuthenticationFilter的前面，目的是除了登录的时候去查询数据库外，其他
                    时候都用token进行认证。*/
                .addFilterBefore(new TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class)
                .addFilter(new TokenLoginFilter(authenticationManager(), redisTemplate, loginLogService));

        // 禁用session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 指定userDetailsService和加密器
        auth.userDetailsService(userDetailsService).passwordEncoder(customMd5PasswordEncoder);
    }

    /**
     * 配置那些请求不拦截
     * 排除Swagger相关请求
     *
     * @param web
     */
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/favicon.ico", "/swagger-resources/**"
                , "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html");
    }
}
